package com.combetter.changxing.ui.activity;

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.text.TextUtils;
import android.view.View;

import com.bumptech.glide.Glide;
import com.clj.fastble.BleManager;
import com.clj.fastble.data.BleDevice;
import com.combetter.changxing.Config;
import com.combetter.changxing.R;
import com.combetter.changxing.bluetooth.AdvDevice;
import com.combetter.changxing.bluetooth.Device;
import com.combetter.changxing.bluetooth.FacilityClient2;
import com.combetter.changxing.databinding.ActivityMineUpgradeBinding;
import com.combetter.changxing.model.CallBack;
import com.combetter.changxing.model.EventMessage;
import com.combetter.changxing.model.Firmware;
import com.combetter.changxing.net.FileDownLoadObserver;
import com.combetter.changxing.ui.base.BaseActivity;
import com.combetter.changxing.ui.view.OnDownLoadClickListener;
import com.combetter.changxing.util.CallBackUtils;
import com.combetter.changxing.util.Check;
import com.combetter.changxing.util.FileUtils;
import com.combetter.changxing.util.LogUtil;
import com.combetter.changxing.viewmodel.MineUpgradeViewModel;


import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;

/**
 * 我的-固件升级
 * <p>
 * Created by 深圳唐龙飞讯科技有限公司 on 2018/6/12.
 */
public class MineUpgradeActivity extends BaseActivity<ActivityMineUpgradeBinding, MineUpgradeViewModel> implements CallBack {
//    private MineUpgradeAdapter adapter;

    private int mConnectState = BluetoothGatt.STATE_DISCONNECTED;

    private final static int REQUEST_CODE_GET_FILE = 1;
    private final static int MSG_PROGRESS = 11;
    private final static int MSG_INFO = 12;

    private Disposable sub;
    private Observable<Long> obser;
    private Device mDevice;

    private BleDevice thisDevice;
    private boolean isExit = false;
    private String isExitFile = "";
    private String version;
    private Double localVersion;
    private int ingProgress = 0;

    private boolean isSupport = false;

    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE};

    @Override
    public int setLayout() {
        EventBus.getDefault().register(this);
        return R.layout.activity_mine_upgrade;
    }

    @Override
    public void init() {
        CallBackUtils.setCallBack(this);

        version = getIntent().getStringExtra("version");

        obser = Observable.interval(700, TimeUnit.MILLISECONDS)
                .observeOn(AndroidSchedulers.mainThread());

        thisDevice = FacilityClient2.getClient().bleDevices;
        if (thisDevice != null && thisDevice.getDevice() != null) {
            AdvDevice advDevice = new AdvDevice(thisDevice.getDevice(), thisDevice.getRssi(), thisDevice.getScanRecord());
            mDevice = new Device(advDevice.device, advDevice.scanRecord, advDevice.rssi);
            mDevice.setDeviceStateCallback(deviceCallback);
        }
        File dir = new File(getExternalFilesDir(null) + File.separator);
        File filelist[] = dir.listFiles();
        for (File f : filelist) {
            String filename = f.getName();
            if (filename.startsWith("wkzjOta")) {
//                isExit = true;
                isExitFile = f.getAbsolutePath();
                FileUtils.deleteFile(isExitFile);
//                localVersion = Double.valueOf(filename.replace("wkzjOta", "").replace(".bin", ""));
            }
        }
        verifyStoragePermissions(this);
    }

    public void startOTA(byte[] firmware) {
        mDevice.startOta(firmware);
    }

    public int returnStatus() {
        return this.mConnectState;
    }




    private void connectToggle() {
        if (mConnectState == BluetoothGatt.STATE_CONNECTED) {
            mDevice.disconnect();
        } else if (mConnectState == BluetoothGatt.STATE_DISCONNECTED) {
            mDevice.connect(this);
            mConnectState = BluetoothGatt.STATE_CONNECTING;
        }
    }

    @Override
    public Class createViewModel() {
        return MineUpgradeViewModel.class;
    }

    @Override
    public void loadData() {
        mViewModel.getFirmware(thisDevice);
    }


    public void showDiscoveringDialog() {
        showWaitingDialog("固件信息请求中...");
    }

    private Device.DeviceStateCallback deviceCallback = new Device.DeviceStateCallback() {
        @Override
        public void onConnected(Device device) {
            LogUtil.w("---" + " # onConnected");
            mConnectState = BluetoothGatt.STATE_CONNECTED;
            runOnUiThread(() -> mBinding.topConnectStatus.setText("已连接"));

        }

        @Override
        public void onDisconnected(Device device) {
            LogUtil.w("---" + " # onDisconnected");
            mConnectState = BluetoothGatt.STATE_DISCONNECTED;
            runOnUiThread(() -> {
//                    mServiceListFragment.clearListData();
                mBinding.topConnectStatus.setText("点击连接设备");
                invalidateOptionsMenu();
                dismissWaitingDialog();
            });
            if (ingProgress > 0 && ingProgress < 100) {
                showWaitingDialog("固件升级失败，请退出重新尝试");
            }
        }

        @Override
        public void onServicesDiscovered(Device device, final List<BluetoothGattService> services) {
            LogUtil.w("---" + " # onServicesDiscovered");
            UUID serviceUUID = null;
            for (BluetoothGattService service : services) {
                for (BluetoothGattCharacteristic characteristic : service.getCharacteristics()) {
                    if (characteristic.getUuid().equals(Device.CHARACTERISTIC_UUID_WRITE)) {
                        serviceUUID = service.getUuid();
                        break;
                    }
                }
            }

            if (serviceUUID != null) {
                device.SERVICE_UUID = serviceUUID;
            }
            runOnUiThread(() -> {

                dismissWaitingDialog();
                mViewModel.update(mBinding.tvDownload);
            });
        }

        @Override
        public void onOtaStateChanged(Device device, int state) {
            LogUtil.w("---" + " # onOtaStateChanged");
            switch (state) {
                case Device.STATE_PROGRESS:
                    LogUtil.w("ota progress : " + device.getOtaProgress());
                    mInfoHandler.obtainMessage(MSG_PROGRESS, device.getOtaProgress()).sendToTarget();
                    break;
                case Device.STATE_SUCCESS:
                    LogUtil.d("ota success : ");
                    mInfoHandler.obtainMessage(MSG_INFO, "ota complete").sendToTarget();
                    break;
                case Device.STATE_FAILURE:
                    LogUtil.d("ota failure : ");
                    mInfoHandler.obtainMessage(MSG_INFO, "ota failure").sendToTarget();
                    break;
            }
        }
    };

    @Override
    public void doSomeThing(Object data) {
        List<Firmware> firmwareList = (List<Firmware>) data;
        if (!Check.isEmpty(firmwareList)) {
            Firmware bean = firmwareList.get(0);
            try {
                mBinding.upgradeName.setText(TextUtils.isEmpty(bean.getGujian_name()) ? "" : bean.getGujian_name());
                mBinding.tvNewVersion.setText(TextUtils.isEmpty(bean.getVersion().toUpperCase()) ? "" : "最新版本：" + bean.getVersion().toUpperCase());
                mBinding.tvTodayVersion.setText(TextUtils.isEmpty(version) ? "" : "当前版本：" + version);
                mBinding.upgradeContent.setText(TextUtils.isEmpty(bean.getRmk()) ? "" : bean.getRmk());

                if (!Check.isEmpty(bean.getPhoto_path())) {
                    Glide.with(MineUpgradeActivity.this).load(Config.URL_BASE_FILE + bean.getPhoto_path()).into(mBinding.ivHead);
                }

                /**
                 *  比较版本号
                 */
                double todayVersion = Double.parseDouble(version.substring(1, version.length()));
                double newVersion = Double.parseDouble(bean.getVersion().substring(1, bean.getVersion().length()).replace(".", ""));
                if (newVersion > todayVersion) {
                    mBinding.tvDownload.setEnabled(true);
//                    if (isExit && newVersion <= localVersion) {
//                        mBinding.tvDownload.finish();
//                        mViewModel.localPath.set(isExitFile);
//                    } else {
                        mBinding.tvDownload.reset();
//                    }
                    sendDownload(bean.getFile_path(), String.valueOf((int) newVersion));
                } else {
                    mBinding.tvDownload.setEnabled(false);
                    mBinding.tvDownload.setCurrentText("已是最新版本");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public void sendDownload(String path, String version) {
        mBinding.tvDownload.setEnablePause(false);
        mBinding.tvDownload.setOnDownLoadClickListener(new OnDownLoadClickListener() {
            @Override
            public void clickDownload() {
                sub = mViewModel.downloadFile(MineUpgradeActivity.this, path, version, new FileDownLoadObserver<File>() {
                    @Override
                    public void onSuccess(File file) {
                        sub.dispose();
                        mViewModel.localPath.set(file.getAbsolutePath());
                    }

                    @Override
                    public void onFail(Throwable throwable) {

                    }

                    @Override
                    public void onProgress(int progress, long total) {
                        LogUtil.e("--progress: " + progress + "    total:" + total);
                        runOnUiThread(() -> mBinding.tvDownload.setProgress(progress));
                    }
                });
            }

            @Override
            public void clickPause() {
                sub.dispose();
            }

            @Override
            public void clickResume() {
                if (isSupport) {
                    clickDownload();
                } else {
                    verifyStoragePermissions(MineUpgradeActivity.this);
                }
            }

            @Override
            public void clickFinish() {
                if (sub != null) {
                    sub.dispose();
                }
                showDiscoveringDialog();
                new Handler().post(() -> {
                    LogUtil.e("clickFinish 下载完毕，开始处理");
                    BleManager.getInstance().disconnectAllDevice();
                    FacilityClient2.getClient().disconnect();
                });
                mInfoHandler.removeMessages(1);
                mInfoHandler.sendEmptyMessageDelayed(1, 5000);
            }


        });
    }

    private void showFinishDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setCancelable(false);
        builder.setTitle("提示").setMessage("固件升级完成，请返回设备页面重新连接").setPositiveButton("确定", (dialog, which) -> {
            dialog.dismiss();
            setResult(RESULT_OK);
            finish();
        });
        builder.show();
    }

    public void tipDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setCancelable(false);
        builder.setTitle("提示").setMessage("固件升级中，请勿操作！").setPositiveButton("确定", (dialog, which) -> {
            dialog.dismiss();
        });
        builder.show();

    }


    private Handler mInfoHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == MSG_PROGRESS) {
                mBinding.tvDownload.setEnablePause(false);
                mBinding.tvDownload.setClickable(false);
//                mBinding.tvDownload.reset();
                ingProgress = (int) msg.obj;

                if (ingProgress == 1) {
                    mBinding.tvDownload.reset();
                }
                mBinding.tvDownload.setProgress(ingProgress);

            } else if (msg.what == MSG_INFO) {
                if (msg.obj.equals("ota complete")) {
                    mBinding.tvDownload.finish();
                    mBinding.tvDownload.setCurrentText("升级完成");
                    FileUtils.deleteFile(isExitFile);
                    ingProgress = 0;
                    if (mDevice != null && mDevice.isConnected()) {
                        mDevice.disconnect();
                    }
//                    Toast.makeText(MineUpgradeActivity.this, msg.obj.toString(), Toast.LENGTH_SHORT).show();
                    showFinishDialog();
                }
            } else if (msg.what == 1) {
                connectToggle();
            }
        }
    };

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void getEventData(EventMessage message) {
        switch (message.getType()) {
            /**
             *  蓝牙连接成功
             */
            case "otaConnected":

                break;
        }
    }

    /**
     * 设置权限
     *
     * @param activity
     */
    public void verifyStoragePermissions(Activity activity) {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            // 查看是否赋予权限
            int permission = ActivityCompat.checkSelfPermission(activity,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if (permission != PackageManager.PERMISSION_GRANTED) {
                // 没有则通知客户
                ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE,
                        REQUEST_EXTERNAL_STORAGE);
            } else {
                isSupport = true;
            }
        } else {
            isSupport = true;
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_EXTERNAL_STORAGE) {
            boolean granted = true;
            for (int result : grantResults) {
                granted = result == PackageManager.PERMISSION_GRANTED;
                if (!granted) {
                    break;
                }
            }
            if (!granted) {
                // 没有赋予权限
            } else {

            }
        }
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        if (mDevice != null && mDevice.isConnected()) {
            mDevice.disconnect();
        }
    }

    public void back(View v) {
        onBackPressed();
    }

    @Override
    public void onBackPressed() {
        if (ingProgress != 0) {
            tipDialog();
        } else {
            this.finish();
        }
    }
}
